<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>碧蓝航线辅助工具-经验油耗比计算器</title>
    <link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v4/jexcel.css" type="text/css" />
    <link rel="stylesheet" href="https://jsuites.net/v4/jsuites.css" type="text/css" />
    <style>
        #fleet .jexcel>tbody>tr>td.readonly {
            color: black;
        }

        #records select {
            width: 200px;
        }
    </style>
</head>

<body>
    <h1>碧蓝航线辅助工具-经验油耗比计算器</h1>
    <div id="records"></div>
    <br>
    自定义名称:
    <br>
    <div id="headers"></div>
    <br>
    自定义战斗内容(暂时未实现潜艇覆盖几率计算逻辑, 请忽略该列):
    <br>
    <div id="fight"></div>
    <br>
    自定义其他收益:
    <br>
    <div id="other"></div>
    <br>
    自定义队伍和经验收益:
    <br>
    <div id="fleet"></div>
    <br>
    <div id="output"></div>

    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"
        integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="https://bossanova.uk/jspreadsheet/v4/jexcel.js"></script>
    <script src="https://jsuites.net/v4/jsuites.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
    <script src="js/storage.js?v=7"></script>
    <script>
        var manager, headerSheet, otherSheet, fleetSheet, fightSheet;
        function onChange() {
            let cur = manager.current();
            cur.headers[0] = cur.name;
            headerSheet.setData([cur.headers]);
            otherSheet.setData(cur.other);
            fleetSheet.setData(cur.fleet);
            fleetSheet.resetSelection();
            fightSheet.setData(cur.fight);
            update();
        }
        manager = initRecordsManager('SheetData', '#records', function () {
            return {
                name: 'New',
                headers: ['New', '计算经验1', '计算经验2', '计算经验3'],
                fleet: [
                    ['道中'],
                    [''],
                    [''],
                    [''],
                    [''],
                    [''],
                    ['潜艇'],
                    [''],
                    [''],
                    ['BOSS'],
                    [''],
                    [''],
                    [''],
                    [''],
                    [''],
                ],
                fight: [],
                other: [],
            }
        }, onChange);

        function initClipBoard() {
            let btnClipboard = createButton('复制全部记录');
            $(btnClipboard).addClass('button-clipboard').attr('data-target', 'all');
            $('#records').append(btnClipboard);

            btnClipboard = createButton('复制当前记录');
            $(btnClipboard).addClass('button-clipboard').attr('data-target', 'cur');
            $('#records').append(btnClipboard);


            let btnImport = createButton('导入记录');
            $('#records').append(btnImport);
            $(btnImport).click(function () {
                let text = prompt('请粘贴导入的记录');
                if (!text) {
                    return;
                }
                try {
                    let records = JSON.parse(text);
                    let idx = manager.data.records.length;
                    manager.data.records.push(...records);
                    manager.data.curIdx = idx;
                    manager.rebuildOptions();
                    onChange();
                    alert(`成功导入${records.length}条记录!`)
                } catch (e) {
                    console.warn(e);
                }
            });

            var clipboard = new ClipboardJS('.button-clipboard', {
                text: function (trigger) {
                    var target = $(trigger).data('target'), data;
                    if (target === 'all') {
                        data = manager.data.records;
                    } else {
                        data = [manager.current()];
                    }
                    return JSON.stringify(data);
                }
            });
            clipboard.on('success', function (e) {
                console.info('clipboard action success:', e.action);
                alert('复制成功');
                e.clearSelection();
            });
        }
        initClipBoard();

        function cancel() {
            return false;
        }
        function callHideIndex(el, obj) {
            obj.hideIndex();
        }
        var cur = manager.current();
        headerSheet = $('#headers').jspreadsheet({
            data: [cur.headers],
            columns: [
                {
                    type: 'text',
                    title: '名称',
                    width: 200,
                },
                {
                    type: 'text',
                    title: '经验1名称',
                },
                {
                    type: 'text',
                    title: '经验2名称',
                },
                {
                    type: 'text',
                    title: '经验3名称',
                },
            ],
            defaultColWidth: 100,
            allowInsertRow: false,
            allowDeleteRow: false,
            // Allow new columns
            allowInsertColumn: false,
            // Allow column delete
            allowDeleteColumn: false,
            columnSorting: false,
            onload: callHideIndex,
            onafterchanges: function () {
                var cur = manager.current();
                cur.headers = headerSheet.getData()[0];
                for (let i of [1, 2, 3]) {
                    fleetSheet.setHeader(i + 2, cur.headers[i] || '-');
                }
                if (cur.headers[0] !== cur.name) {
                    cur.name = cur.headers[0];
                    manager.rebuildOptions();
                }
                update();
            }
        });
        otherSheet = $('#other').jspreadsheet({
            data: cur.other,
            columns: [
                {
                    type: 'numeric',
                    title: '数值',
                },
                {
                    type: 'text',
                    title: '名称',
                },
            ],
            defaultColWidth: 100,
            allowInsertRow: true,
            allowInsertRow: true,
            // Allow new columns
            allowInsertColumn: false,
            // Allow column delete
            allowDeleteColumn: false,
            columnSorting: false,
            onafterchanges: function () {
                update();
            },
            minDimensions: [2, 2]
        });

        fleetSheet = $('#fleet').jspreadsheet({
            data: cur.fleet,
            columns: [
                {
                    type: 'text',
                    title: '类型',
                    readOnly: true,
                    width: 120,
                },
                {
                    type: 'numeric',
                    title: '油耗',
                    width: 80,
                },
                {
                    type: 'numeric',
                    title: 'MVP优先级',
                    width: 100
                },
                {
                    type: 'checkbox',
                    title: '经验1',
                    width: 80
                },
                {
                    type: 'checkbox',
                    title: '经验2',
                    width: 80
                },
                {
                    type: 'checkbox',
                    title: '经验3',
                    width: 80
                },
                {
                    type: 'numeric',
                    title: '额外经验(%)',
                    width: 120
                },
                {
                    type: 'text',
                    title: '备注',
                    width: 120
                },
            ],
            mergeCells: {
                A1: [1, 6],
                A7: [1, 3],
                A10: [1, 6],
            },
            contextMenu: cancel,
            allowInsertRow: false,
            allowDeleteRow: false,
            // Allow new columns
            allowInsertColumn: false,
            // Allow column delete
            allowDeleteColumn: false,
            columnSorting: false,
            onload: callHideIndex,
            onafterchanges: function () {
                console.log('update');
                update();
            }
        });
        headerSheet.onafterchanges();
        fleetSheet.resetSelection()

        fightSheet = $('#fight').jspreadsheet({
            data: cur.fight,
            columns: [
                {
                    type: 'numeric',
                    title: '次数',
                    width: 120,
                },
                {
                    type: 'numeric',
                    title: '经验',
                    width: 80,
                },
                {
                    type: 'numeric',
                    title: '潜艇覆盖几率',
                    width: 150,
                },
                {
                    type: 'checkbox',
                    title: '使用Boss队',
                    width: 100,
                },
                {
                    type: 'text',
                    title: '备注',
                    width: 100,
                },
            ],
            // Allow new columns
            allowInsertColumn: false,
            // Allow column delete
            allowDeleteColumn: false,
            columnSorting: false,
            minDimensions: [5, 2],
            onafterchanges: function () {
                console.log('update');
                update();
            }
        });
        headerSheet.onafterchanges();

        function loadFleet(rows, name, flagShipBuff = true) {
            let res = [];
            for (let [idx, row] of rows.entries()) {
                let oil = parseInt(row[1]);
                if (!oil) {
                    continue;
                }
                res.push({
                    name: `${name}-${idx + 1}`,
                    oil: oil,
                    mvp: parseFloat(row[2]) || 0,
                    gains: row.slice(3, 6).map(Boolean),
                    ratio: 1.2 * (100 + (parseFloat(row[6]) || 0)) / 100,
                });
            }
            if (flagShipBuff && res[0]) {
                res[0].ratio *= 1.5;
            }
            console.log('loadFleet', res);
            return res;
        }

        function update() {
            let cur = manager.current();
            let bossInfo = null;
            let fights = [];
            for (let row of cur.fight) {
                if (!row[1]) {
                    continue;
                }
                let cnt = row[0] || 1;
                let gain = parseInt(row[1]);
                for (let i = 0; i < cnt; ++i) {
                    fights.push({
                        exp: gain,
                        subChance: parseFloat(row[2]),
                        useBoss: row[3] ? 1 : 0,
                    });
                }
            }

            let fleetRoute = loadFleet(cur.fleet.slice(0, 6), '道中');
            let fleetSub = loadFleet(cur.fleet.slice(6, 9), '潜艇', false);
            let fleetBoss = loadFleet(cur.fleet.slice(9), 'Boss');


            let subExp = [];
            let submarineFightCount = Math.min(fights.length, fleetSub.length * 2);
            console.log('潜艇战斗次数', submarineFightCount);

            let totalOil = 10;
            let fightRecords = [];
            for (let [idx, f] of fights.entries()) {
                let recs = [];
                let mvpIdx = 0;
                let mvpWeight = -1;
                if (!f.useBoss) {
                    for (let s of fleetRoute) {
                        if (mvpWeight < s.mvp) {
                            mvpIdx = recs.length;
                            mvpWeight = s.mvp;
                        }
                        totalOil += s.oil;
                        recs.push({ ...s, exp: f.exp });
                    }
                } else {
                    for (let s of fleetBoss) {
                        if (mvpWeight < s.mvp) {
                            mvpIdx = recs.length;
                            mvpWeight = s.mvp;
                        }
                        totalOil += s.oil;
                        recs.push({ ...s, exp: f.exp });
                    }
                }
                if (idx < submarineFightCount) {
                    for (let s of fleetSub) {
                        console.log(mvpWeight, s);
                        if (mvpWeight < s.mvp) {
                            mvpIdx = recs.length;
                            mvpWeight = s.mvp;
                        }
                        totalOil += s.oil;
                        recs.push({ ...s, exp: f.exp });
                    }
                }
                if (!recs.length) {
                    continue;
                }
                // MVP 2倍经验
                recs[mvpIdx].ratio *= 2;
                fightRecords.push({
                    idx: idx + 1,
                    mvp: mvpIdx,
                    ships: recs,
                });
            }
            $('#output').html('<summary><details></details></summary>');
            var details = $('#output details')
            let totalExp = [0, 0, 0];
            for (let record of fightRecords) {
                details.append(`战斗${record.idx}:<br>`)
                for (let s of record.ships) {
                    details.append(`${s.name}: `);
                    for (let i of [0, 1, 2]) {
                        details.append(`${s.gains[i] ? 1 : 0}, `);
                        totalExp[i] += (s.gains[i] ? 1 : 0) * s.ratio * s.exp;
                    }
                    details.append(`${(s.ratio * s.exp).toFixed(3)}<br>`);
                }
                details.append(`<br>`);
            }

            $('#output').append(`油耗: ${totalOil}<br><br>`);
            let extra = false;
            for (let row of cur.other) {
                let cnt = parseFloat(row[0]);
                if (cnt) {
                    $('#output').append(`获取 ${row[0]} ${row[1]}, 油耗比 ${(cnt / totalOil).toFixed(3)}<br>`)
                    extra = true;
                }
            }
            if (extra) {
                $('#output').append('<br>');
            }

            let oilRatio = totalExp.map((v) => (v / totalOil).toFixed(3));
            for (let i of [0, 1, 2]) {
                if (!totalExp[i]) {
                    continue;
                }
                $('#output').append(`${cur.headers[i + 1]}: 经验${totalExp[i].toFixed(3)} 油耗比: ${oilRatio[i]}<br>`);
            }
            $('#output').append('<br>');
            $('#output').append($('#output summary'));
        }
        onChange();
    </script>

</body>

</html>